package com.idanchuang.count.service.impl;

import com.idanchuang.component.core.util.StringUtil;
import com.idanchuang.count.core.entity.ResetCommand;
import com.idanchuang.count.core.model.BizProperties;
import com.idanchuang.count.dao.CountDao;
import com.idanchuang.count.service.SimpleCountService;
import com.idanchuang.count.service.api.request.command.CountBatchResetCommand;
import com.idanchuang.count.service.api.request.command.ResetItem;
import com.idanchuang.count.service.api.request.query.CountBatchQuery;
import com.idanchuang.count.service.api.request.query.CountQuery;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import static com.idanchuang.count.core.util.keyformat.SimpleCountKeysFormatter.formatCountKey;

/**
 * @author Richard_yyf
 * @version 1.0 2021/9/23
 */
@Service
@Slf4j
public class SimpleCountServiceImpl implements SimpleCountService {

    @Resource
    private CountDao countDao;

    @Resource
    private BizProperties bizProperties;

    @Override
    public Long query(CountQuery countQuery) {

        Integer bizId = bizProperties.getBizId(countQuery.getBizCode());

        return countDao.getCount(formatCountKey(bizId, countQuery.getBizNo()));
    }

    @Override
    public Map<String, Long> batchQuery(CountBatchQuery countBatchQuery) {

        Integer bizId = bizProperties.getBizId(countBatchQuery.getBizCode());

        List<String> countKeys = countBatchQuery.getBizNos()
                .stream()
                .filter(StringUtil::isNotEmpty)
                .map(bizNo -> formatCountKey(bizId, bizNo))
                .collect(Collectors.toList());

        List<Long> countValues = countDao.multiGetCount(countKeys);

        Map<String, Long> countMap = new HashMap<>(countKeys.size());
        for (int i = 0; i < countBatchQuery.getBizNos().size(); i++) {
            if (countValues.get(i) == null) {
                continue;
            }
            countMap.put(countBatchQuery.getBizNos().get(i), countValues.get(i));
        }

        return countMap;
    }

    @Override
    public void batchResetCount(CountBatchResetCommand countBatchResetCommand) {

        Integer bizId = bizProperties.getBizId(countBatchResetCommand.getBizCode());
        List<ResetCommand> resetCommands = new ArrayList<>(countBatchResetCommand.getItems().size());
        for (ResetItem resetItem : countBatchResetCommand.getItems()) {
            if (resetItem == null) {
                continue;
            }
            if (resetItem.getBizNo() == null || resetItem.getVal() == null) {
                log.error("ignore invalid reset command: {}", resetItem);
                continue;
            }
            resetCommands.add(new ResetCommand(formatCountKey(bizId, resetItem.getBizNo()), resetItem.getVal()));
        }
        countDao.batchSet(resetCommands);
    }
}
